<?php
/**
 * モデル（データアクセス）既定クラス
 */
require_once 'Xml.php';
require_once 'Session.php';

/**
 * モデル（データアクセス）基底クラス
 * @author admin
 *
 */
class Models_Controller
{
	/** データＩＤ */
	const KEY_ID = 'ID';

	/** パース配列リスト開始キー */
	const KEY_LIST      = 'LIST';
	/** セッションキー：フォルダー名 */
	const SESSIONKEY_FOLDER = 'models_folder';

	/**********************
	* メンバ変数
	*/

	/** @var 処理中にエラーが検出された場合ＴＲＵＥを設定する */
	public $bErrorExists=FALSE;

	/** @var データセット */
	protected $_aryDataSet;

	/** @var XMLファイル名 */
	protected $_strFileName;

	/**
	 * アプリケーション共通のデータフォルダー名をセッションに保存する
	 * （チーム毎にフォルダーを分けることが目的で作成された）
	 * @param $strFolder
	 */
	public static function setFolder($strFolder){
		$objSession = new Lib_Session();
		$objSession->setValue(self::SESSIONKEY_FOLDER, $strFolder);
	}

	/**
	 * アプリケーション共通のデータフォルダー名をセッションから取得する
	 */
	protected function _getFolder()
	{
		$result = self::getFolder();
		return $result;
	}

	/**
	 * アプリケーション共通のデータフォルダー名をセッションから取得する(スタティック版）
	 */
	public static function getFolder()
	{
		$objSession = new Lib_Session();
		$result = $objSession->getValue(self::SESSIONKEY_FOLDER);
		if ($result != ''){
			$result .= '/';
		}
		return $result;
	}

	/**
	 * データセット取得
	 */
	public function getDataset()
	{
		return $this->_aryDataSet;
	}

	/**
	 * データＩＤ検索（公開版）
	 * @param $sId データＩＤ
	 * @return array|boolean 検索結果（コピー返し）
	 */
	public function searchId($sId)
	{
		$aryResult = $this->_searchId($sId);
		return $aryResult;
	}

	/**
	 * データID検索
	 * Enter description here ...
	 * @param string $sId データＩＤ
	 * @return array|boolean 検索結果 リファレンス返し|FALSE
	 */
	protected function &_searchId($sId)
	{
		$i = 0;
		$iCount = count($this->_aryDataSet);
		/***
		 * すべてのデータを捜査
		 */
		while ( $i < $iCount ) {
			/*** ID一致判定 */
			if ( $this->_aryDataSet[$i][self::KEY_ID] == $sId) {
				return $this->_aryDataSet[$i];
			}
			$i ++;
		}
		$bResult = FALSE;
		return $bResult;
	}

	/**
	 * 削除
	 * Enter description here ...
	 * @param unknown_type $sId
	 */
	public function delelte($sId)
	{
		$i = 0;
		$iCount = count($this->_aryDataSet);
		/***
		 * 全データ捜査
		 */
		while ( $i < $iCount ) {
			/*** ID一致判定 */
			if ( $this->_aryDataSet[$i][self::KEY_ID] == $sId) {
				unset($this->_aryDataSet[$i]);
				return TRUE;
			}
			$i ++;
		}
		return  FALSE;
	}

	/**
	 * 追加更新
	 * @param unknown_type $dataSet
	 * @param unknown_type $iD
	 */
	public function replace($dataSet, $iD='')
	{
		/** ＩＤ設置判定 */
		if ($iD != '') {
			$refDataset = &$this->_searchId($iD);
		} else {
			$refDataset = array();
			$refDataset[self::KEY_ID] = self::createId();
		}

		/*** カラムサーチ */
		foreach ($dataSet as $key =>$column) {
			// データセットに同一カラムがあれば値を設置
			if (key_exists($key, $refDataset)) {
				$refDataset[$key] = $column;
			}
		}

		/** ID設置による追加更新判定 */
		if ($iD == '') {
			$this->_aryDataSet[] = $refDataset;
		}
	}

	/**
	 * 空の配列項目を削除する
	 * @param unknown_type $dataSet
	 */
	public static function unsetEmptyCulumn($dataSet)
	{
		$iCount = count($dataSet);
		$i = 0;
		/*** 空白配列項目検索 */
		while ($i < $iCount) {
			/*** 空白判定 */
			if ($dataSet[$i] == '') {
				unset($dataSet[$i]);
			}
			$i ++;
		}
		$result = array_merge($dataSet);
		return $result;
	}

	/**
	 * 生成データセットのカラムが十分か判定（仮想）
	 * @param unknown_type $dataSet
	 * @return boolean
	 */
	protected function _isEnoughColumn($dataSet) {
		return TRUE;
	}

	/**
	* ID生成
	* Enter description here ...
	*/
	public static function createId()
	{
		$aryDivide = explode( ' ', microtime() );
		$iResult = $aryDivide[0] + $aryDivide[1];
		return $iResult;
	}

	/**
	 * XMLファイル形式のデータファイルを読み込む
	 * Enter description here ...
	 * @param string $strFileName
	 */
	public function loadFromFile( $strFileName, $aryForceListKey=array() )
	{
		$this->_strFileName = $strFileName;
		$objXml = new Lib_Xml;
		$aryForceListKey[] = self::KEY_LIST;
		$aryDataset = $objXml->loadFromFile( $strFileName,  $aryForceListKey );
		/*** データ入力に失敗 */
		if ( $aryDataset === FALSE ) {
			$this->_aryDataSet = FALSE;
			$this->bErrorExists = TRUE;
			return FALSE;
		}
		$this->_aryDataSet = $aryDataset[self::KEY_LIST];

		/***
		 * 不整合IDを抹消する
		*/
		$iCount = count( $this->_aryDataSet );
		$i = 0;
		/***
		 * 全データ捜査
		 */
		while ( $i < $iCount ) {
			/***
			 * IDが未設定の場合データ抹消
			 */
			if ( !isset( $this->_aryDataSet[$i][self::KEY_ID] ) ) {
				unset( $this->_aryDataSet[$i] );
			} else if ( $this->_aryDataSet[$i][self::KEY_ID] == '' ) {
				unset( $this->_aryDataSet[$i] );
			}
			$i ++;
		}
		return $this->_aryDataSet;
	}

	/**
	 * XML形式でファイルに保存する
	 * Enter description here ...
	 * @param string $strFileName
	 */
	public function saveToFile( $strFileName = '')
	{
		/***
		 * そもそもデータの入力に失敗している
		 */
		if ( $this->_aryDataSet === FALSE ) {
			return FALSE;
		}
		/***
		 * ファイル名が未指定の場合、入力ファイルと同じファイルに出力する
		 */
		if ( $strFileName == '' ) {
			/*** 入力ファイルと同じファイルに出力する */
			if ( $this->_strFileName != '' ) {
				$strFileName = $this->_strFileName;
			} else {
				return FALSE;
			}
		}
		$aryDataset[self::KEY_LIST] = $this->_aryDataSet;
		$objXml = new Lib_Xml;
		$objXml->aryXml = $aryDataset;
		$status = $objXml->saveToFile( $strFileName );
		return $status;
	}

	/**
	 * クリア
	 */
	public function clear()
	{
		$this->_aryDataSet = array();
	}

	protected function _createRelationObject($sFileName)
	{
		$this->_objRelation = new Models_Relation_Xml($sFileName, array(self::KEY_LIST));
	}

}